class_name FireBullet
extends Node2D

@export var speed: float = 200
@export var dir: Vector2 = Vector2.RIGHT
@export var max_life_time: float = 5.0

@onready var point_light_2d: PointLight2D = $PointLight2D

@onready var hit_area: Area2D = $HitArea
var is_destroy: bool = false

var sender: Node2D
var attack: float = 0
var critical_rate: float = 0
var critical_bonus: float = 0
var knockback: float = 0
var hit_cam_shake_strength: float = 0
var hit_cam_shake_duration: float = 0

@onready var shoot_audio: AudioStreamPlayer2D = $AudioStreamPlayer2D
@onready var explosion_audio: AudioStreamPlayer2D = $AudioStreamPlayer2D2
@onready var fire_audio: AudioStreamPlayer2D = $AudioStreamPlayer2D3


func _ready() -> void:
	shoot_audio.play()
	fire_audio.play()
	
	await get_tree().create_timer(max_life_time).timeout
	if not is_destroy:
		fade_destroy()


func fade_destroy():
	if is_destroy: return
	
	fire_audio.stop()
	explosion_audio.play()
	
	is_destroy = true
	
	var tween = create_tween()
	tween.tween_property(point_light_2d, "energy", 0, 0.3) \
	.set_trans(Tween.TRANS_SINE) \
	.set_ease(Tween.EASE_OUT).from_current()
	
	var tween_alpha = create_tween()
	tween_alpha.tween_property(self, "modulate:a", 0, 0.3) \
	.set_trans(Tween.TRANS_SINE) \
	.set_ease(Tween.EASE_OUT).from_current()
	await tween_alpha.finished
	
	queue_free()


func _physics_process(delta: float) -> void:
	process_move(delta)
	process_hit(delta)
	
	
func process_hit(delta: float):
	if is_destroy: return
	
	var areas = hit_area.get_overlapping_areas()
	if areas.size() <= 0: return
	
	for area in areas:
		var source = area.source
		
		var hit_data = get_hit_data()
		source.take_hit(hit_data, sender)
	
	var level = get_tree().current_scene as Level
	level.emit_particle("particle_fire_hit_effect", global_position)
	level.camera.start_shake(hit_cam_shake_strength, hit_cam_shake_duration)
	fade_destroy()
			
			
func get_hit_data():
	var is_critical = randf() <= critical_rate
	var critical_attack = attack * (1.0 + critical_bonus)
	
	var hit_data = HitData.new()
	hit_data.is_critical = is_critical
	hit_data.attack = critical_attack if is_critical else attack
	hit_data.knockback = knockback
	
	return hit_data
	
	
func process_move(delta):
	if is_destroy: return
	
	var velocity = dir * speed
	position += velocity * delta
	
	
func set_is_enemy(b: bool):
	if b:
		hit_area.set_collision_mask_value(7, true)
		hit_area.set_collision_mask_value(6, false)
	else:
		hit_area.set_collision_mask_value(7, false)
		hit_area.set_collision_mask_value(6, true)


func _on_hit_area_body_entered(body: Node2D) -> void:
	var level = get_tree().current_scene as Level
	level.emit_particle("particle_fire_hit_effect", global_position)
	level.camera.start_shake(hit_cam_shake_strength, hit_cam_shake_duration)
	fade_destroy()
